/**
 * 初始化创建数据库
 */
import { model, connect, connection } from "mongoose";
import { dbUrl } from "../common";
import "./conn";

interface ITCreateParam {
  schematype: any;
  modalname: string;
  param?: any;
  callback?: (data?: any, count?: number) => void;
}

export const createMDB = async (data: ITCreateParam) => {
  await connect(dbUrl, (err: any) => {
    if (!err) {
      const { schematype, modalname } = data;
      // const modelSchema = new Schema(schematype);
      const SchemaModel = model(modalname, schematype);
      SchemaModel.init(function () {
        connection.close();
      });
    }
  });
};

export const findAll = (data: ITCreateParam) => {
  const { callback, schematype, modalname } = data;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find({}, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

export const findByPage = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const SchemaModel = model(modalname, schematype);
  const page = param.page;
  const limit = param.pageSize || 5;
  SchemaModel.count({}, (cerror: any, count: number) => {
    if (!cerror) {
      SchemaModel.find({})
        .skip((page - 1) * parseInt(limit))
        .limit(parseInt(limit))
        .exec((error: any, result: any) => {
          if (!error && !!callback) {
            callback(result, count);
          }
        });
    }
  });
};

/**
 * 根据用户查询条件分页查询数据
 *
 * @param data 查询参数对象
 * @param data.callback 查询完成后的回调函数，回调函数接收两个参数，分别是查询结果和总记录数
 * @param data.schematype Schema类型
 * @param data.modalname Schema名称
 * @param data.param 查询参数，包含分页信息
 * @param data.param.page 当前页码
 * @param data.param.pageSize 每页显示的记录数，默认为5
 */
export const findByUserPage = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const SchemaModel = model(modalname, schematype);
  const user = param.user;
  const page = param.page;
  const limit = param.pageSize || 5;

  // 构建查询条件对象
  const query: any = {};
  if (user) {
    query.user = user; // 假设数据模型中有一个名为 user 的字段来存储用户信息
  }

  SchemaModel.count(query, (cerror: any, count: number) => {
    if (!cerror) {
      SchemaModel.find(query)
        .skip((page - 1) * parseInt(limit))
        .limit(parseInt(limit))
        .exec((error: any, result: any) => {
          if (!error && !!callback) {
            callback(result, count);
          }
        });
    }
  });
};

export const addData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const SchemaModel = model(modalname, schematype);

  SchemaModel.create(param, (error: any, result: any) => {
    if (!!callback) {
      if (!error) {
        callback(result);
      } else {
        if (error.code === 11000) {
          callback({ success: false, message: "duplicate" });
        }
      }
    }
  });
};

export const updateData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id, ...modifydata } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.findOneAndUpdate(
    { _id: id },
    modifydata,
    (error: any, result: any) => {
      if (!error && !!callback) {
        callback(result);
      }
    }
  );
};

export const updateUserData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id, user, ...modifydata } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.findOneAndUpdate(
    { _id: id, user },
    modifydata,
    (error: any, result: any) => {
      if (!error && !!callback) {
        callback(result);
      }
    }
  );
};

export const upDateDataByIdsync = async (data: ITCreateParam) => {
  const { schematype, modalname, param } = data;
  const { id, ...modifydata } = param;
  const SchemaModel = model(modalname, schematype);
  const result = await SchemaModel.findByIdAndUpdate(id, modifydata).exec();
  return result;
};

export const deleteData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.findOneAndDelete({ _id: id }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback();
    }
  });
};

export const deleteUserData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id, user } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.findOneAndDelete({ _id: id, user }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback();
    }
  });
};

// export const deleteDataAsync = async (data: ITCreateParam) => {
//   const { schematype, modalname, param } = data;
//   const { id } = param;
//   const SchemaModel = model(modalname, schematype);
//   const result = await SchemaModel.findOneAndDelete({ _id: id }).exec();
//   return result;
// };

// export const deleteManyDataAsync = async (data: ITCreateParam) => {
//   const { schematype, modalname, param } = data;
//   const { ids } = param;
//   const SchemaModel = model(modalname, schematype);
//   const result = await SchemaModel.deleteMany({ _id: ids }).exec();
//   return result;
// };

export const getValueData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find({ pid: id }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

export const findUser = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { account, password } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find({ account, password }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

export const findUserById = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find({ _id: id }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

// 批量插入数据
export const importData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const SchemaModel = model(modalname, schematype);

  SchemaModel.collection.insertMany(param, (error: any, result: any) => {
    if (!!callback) {
      if (!error) {
        callback(result);
      } else {
        if (error.code === 11000) {
          callback({ success: false, message: "duplicate" });
        }
      }
    }
  });
};

// 搜索化学试剂
export const searchreagent = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { keyword } = param;
  const reg = new RegExp(keyword, "i");
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find(
    {
      $or: [
        { name: { $regex: reg } },
        { cnname: { $regex: reg } },
        { abbreviation: { $regex: reg } },
        { casno: { $regex: reg } },
        { formula: { $regex: reg } },
      ],
    },
    (error: any, result: any) => {
      if (!error && !!callback) {
        callback(result);
      }
    }
  );
};

export const searchuserreagent = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { keyword, user } = param;
  const reg = new RegExp(keyword, "i");
  const SchemaModel = model(modalname, schematype);

  // 构建查询条件对象
  const query: any = {
    $or: [
      { name: { $regex: reg } },
      { cnname: { $regex: reg } },
      { abbreviation: { $regex: reg } },
      { casno: { $regex: reg } },
      { formula: { $regex: reg } },
    ],
  };

  query.user = user;

  SchemaModel.find(query, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

// 根据id查询实验设计
export const findById = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find({ _id: id }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

// 异步根据id查询实验设计
export const findOneByIdsync = async (data: ITCreateParam) => {
  const { schematype, modalname, param } = data;
  const { id } = param;
  const SchemaModel = model(modalname, schematype);
  const result = await SchemaModel.findOne({ _id: id }).exec();
  return result;
};

// 校验用户
export const findAccount = async (data: ITCreateParam) => {
  const { schematype, modalname, param } = data;
  const { account, email } = param;
  const SchemaModel = model(modalname, schematype);
  const result = await SchemaModel.findOne({ account, email }).exec();
  return result;
};

export const findDesignerByUserId = async (data: ITCreateParam) => {
  const { schematype, modalname, param } = data;
  const { userId } = param;
  const SchemaModel = model(modalname, schematype);
  const result = await SchemaModel.find({ "userInfo.id": userId }).exec();
  return result;
};

export const findDesignerlist = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { designer } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.find({ designer }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback(result);
    }
  });
};

export const deleteReactionDesignerData = (data: ITCreateParam) => {
  const { callback, schematype, modalname, param } = data;
  const { id } = param;
  const SchemaModel = model(modalname, schematype);
  SchemaModel.findOneAndDelete({ designer: id }, (error: any, result: any) => {
    if (!error && !!callback) {
      callback();
    }
  });
};

// 根据id查询实验设计试剂
// export const findReagentById = (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const { designerId } = param;
//   const SchemaModel = model(modalname, schematype);
//   SchemaModel.find({ designerId }, (error: any, result: any) => {
//     if (!error && !!callback) {
//       callback(result);
//     }
//   });
// };

// 根据参数删除所有
// export const deleteDataByParam = (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const SchemaModel = model(modalname, schematype);
//   SchemaModel.deleteMany(param, (error: any, result: any) => {
//     if (!error && !!callback) {
//       callback();
//     }
//   });
// };

// 删除反应试剂
// export const deleteReactorReagents = (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const { reactorid } = param;
//   const SchemaModel = model(modalname, schematype);
//   SchemaModel.findOneAndDelete(
//     { _id: reactorid },
//     (error: any, result: any) => {
//       if (!error && !!callback) {
//         callback();
//       }
//     }
//   );
// };

// 根据id删除数组子项
// export const deleteReactorReagents = (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const { designerId, reactorReagentIds } = param;
//   const SchemaModel = model(modalname, schematype);
//   SchemaModel.updateMany(
//     { _id: designerId },
//     { $pull: { reactorReagents: { _id: reactorReagentIds[0] } } },
//     { multi: true },
//     (error: any, result: any) => {
//       if (!error && !!callback) {
//         callback();
//       }
//     }
//   );
// };

// 更新用于反应的试剂
// export const upReactorReagentData = async (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const { datas } = param;
//   const SchemaModel = model(modalname, schematype);

//   const bulkOps: any = [];
//   datas.forEach(async (item: any) => {
//     const { id, amount, reactors } = item;
//     bulkOps.push({
//       updateOne: {
//         filter: {
//           _id: id,
//         },
//         update: {
//           amount,
//           $push: { reactors: { $each: reactors } },
//         },
//       },
//     });
//   });

//   SchemaModel.bulkWrite(bulkOps)
//     .then((result: any) => {
//       if (callback) {
//         callback(result);
//       }
//     })
//     .catch((error: any) => {
//       if (callback) {
//         callback({ success: false, message: error });
//       }
//     });
// };

// 新增实验设计反应试剂信息
// export const addDesignerReactorReagentData = async (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const { id, reactorReagents } = param;
//   const SchemaModel = model(modalname, schematype);

//   const bulkOps: any = [
//     {
//       updateOne: {
//         filter: {
//           _id: id,
//         },
//         update: {
//           $push: { reactorReagents },
//         },
//       },
//     },
//   ];

//   SchemaModel.bulkWrite(bulkOps)
//     .then((result: any) => {
//       if (callback) {
//         callback(result);
//       }
//     })
//     .catch((error: any) => {
//       if (callback) {
//         callback({ success: false, message: error });
//       }
//     });
// };

// 根据id查询实验设计反应试剂
// export const findReactorById = (data: ITCreateParam) => {
//   const { callback, schematype, modalname, param } = data;
//   const { designerId } = param;
//   const SchemaModel = model(modalname, schematype);
//   SchemaModel.find({ designerId }, (error: any, result: any) => {
//     if (!error && !!callback) {
//       callback(result);
//     }
//   });
// };

// 根据rid和uid查询用于反应的试剂信息
// export const searchReagentByUid = async (data: ITCreateParam) => {
//   const { schematype, modalname, param } = data;

//   const rids: any = [];
//   if (param && param.length) {
//     param.forEach(({ rid }: any) => {
//       rids.push(rid);
//     });
//   }

//   // 传入的amount是要删除的数量，所以在删除前与原来的数量相加
//   const SchemaModel = model(modalname, schematype);
//   let searchResult: any = null;
//   try {
//     searchResult = await SchemaModel.find({ _id: rids }).exec();
//   } catch (e) {}
//   if (searchResult && searchResult.length) {
//     searchResult.forEach(({ _id, amount }: any) => {
//       param.some((item: any) => {
//         if (_id.toString() === item.rid) {
//           item.amount = item.amount + amount;
//           return true;
//         }
//       });
//     });
//   }

//   const bulkOps: any = [];
//   param.forEach((item: any) => {
//     const { rid, amount, uid } = item;
//     bulkOps.push({
//       updateOne: {
//         filter: {
//           _id: rid,
//         },
//         update: {
//           amount,
//           $pull: { reactors: { uid } },
//         },
//       },
//     });
//   });

//   await SchemaModel.bulkWrite(bulkOps);
// };

// 清除反应试剂时恢复所有实验试剂
// export const searchReagentsByUids = async (data: ITCreateParam) => {
//   const { schematype, modalname, param } = data;
//   const rids: any = [];
//   if (param && param.length) {
//     param.forEach(({ fromids }: any) => {
//       if (fromids && fromids.length) {
//         fromids.forEach(({ rid }: any) => {
//           rids.push(rid);
//         });
//       }
//     });
//   }

//   // 传入的amount是要删除的数量，所以在删除前与原来的数量相加
//   const SchemaModel = model(modalname, schematype);
//   let searchResult: any = null;
//   try {
//     searchResult = await SchemaModel.find({ _id: rids }).exec();
//   } catch (e) {}
//   if (searchResult && searchResult.length) {
//     searchResult.forEach(({ _id, amount }: any) => {
//       param.some(({ fromids }: any) => {
//         if (fromids && fromids.length) {
//           fromids.some((item: any) => {
//             if (_id.toString() === item.rid) {
//               item.amount = item.amount + amount;
//             }
//           });
//           return true;
//         }
//       });
//     });
//   }
//   console.log("这里还原有问题，需要修改！！");

//   const bulkOps: any = [];
//   param.forEach(({ fromids }: any) => {
//     if (fromids && fromids.length) {
//       fromids.forEach((item: any) => {
//         const { rid, amount, uid } = item;
//         bulkOps.push({
//           updateOne: {
//             filter: {
//               _id: rid,
//             },
//             update: {
//               amount,
//               $pull: { reactors: { uid } },
//             },
//           },
//         });
//       });
//     }
//   });
//   await SchemaModel.bulkWrite(bulkOps);
// };
